/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.saber.certificacao.modelos;

import br.com.saber.certificacao.enums.TipoProva;
import br.com.saber.certificacao.modelos.relacionamentos.ProvaQuestao;
import br.com.saber.certificacao.modelos.validadores.interfaces.ValidadoInterface;
import java.util.Date;
import java.util.Set;
import java.util.TreeSet;
import javax.persistence.*;

/**
 *
 * @author gbvbahia
 */
@Entity
@Table(name = "provas")
public class Prova implements ValidadoInterface, Comparable<Prova> {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, unique = true)
    private Long id;

    @Column(name = "certificacao", nullable = false, unique = false)
    private String certificacao;

    @Column(name = "versao_nome", nullable = false, unique = false)
    private String versaoNome;
    
    @Column(name = "multipla_versao", nullable = false, unique = false)
    private boolean multiplaVersao;

    @Enumerated(EnumType.STRING)
    @Column(name = "tipo_prova", nullable = false, unique = false)
    private TipoProva tipoProva;

    @Column(name = "nota_passar", nullable = false, unique = false)
    private Double notaParaPassar;

    @Column(name = "nota_tirada", nullable = true, unique = false)
    private Double notaTirada;

    @Column(name = "prova_terminada", nullable = false, unique = false)
    private boolean provaTerminada;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "data_criacao", nullable = false, unique = false)
    private Date dataCriacao;

    @OneToMany(targetEntity = br.com.saber.certificacao.modelos.relacionamentos.ProvaQuestao.class,
    mappedBy = "prova", fetch = FetchType.EAGER, cascade=CascadeType.MERGE)
    private Set<ProvaQuestao> questoesDestaProva;

    @ManyToOne(targetEntity=br.com.saber.certificacao.modelos.Usuario.class, fetch=FetchType.EAGER)
    @JoinColumn(name="usuario_id", referencedColumnName="id", nullable=false)
    private Usuario aluno;

    public Prova(String certificacao, String versaoNome, boolean multiplaVersao, TipoProva tipoProva, Double notaParaPassar, Double notaTirada, boolean provaTerminada) {
        this.certificacao = certificacao;
        this.versaoNome = versaoNome;
        this.tipoProva = tipoProva;
        this.notaParaPassar = notaParaPassar;
        this.notaTirada = notaTirada;
        this.provaTerminada = provaTerminada;
        this.multiplaVersao = multiplaVersao;
        this.dataCriacao = new Date();
    }

    public Prova() {
    }

    /**
     * Representa o aluno que está fazendo esta prova.
     * @return O aluno que solicitou a prova.
     */
    public Usuario getAluno() {
        return aluno;
    }

    /**
     * Representa o aluno que está fazendo esta prova.
     * @param aluno
     */
    public void setAluno(Usuario aluno) {
        this.aluno = aluno;
    }

    /**
     * Represeta todas as questões que caem nesta prova, com suas respostas
     * marcadas.
     * @return Um set com todas as questões da prova.
     */
    public Set<ProvaQuestao> getQuestoesDestaProva() {
        if (this.questoesDestaProva == null) {
            questoesDestaProva = new TreeSet<ProvaQuestao>();
        }
        return questoesDestaProva;
    }

    /**
     * Represeta todas as questões que caem nesta prova, com suas respostas
     * marcadas.
     * @param questoesDestaProva
     */
    public void setQuestoesDestaProva(Set<ProvaQuestao> questoesDestaProva) {
        this.questoesDestaProva = questoesDestaProva;
    }

    public String getCertificacao() {
        return certificacao;
    }

    public void setCertificacao(String certificacao) {
        this.certificacao = certificacao;
    }

    public Double getNotaParaPassar() {
        return notaParaPassar;
    }

    public void setNotaParaPassar(Double notaParaPassar) {
        this.notaParaPassar = notaParaPassar;
    }

    public Double getNotaTirada() {
        return notaTirada;
    }

    public void setNotaTirada(Double notaTirada) {
        this.notaTirada = notaTirada;
    }

    public boolean isProvaTerminada() {
        return provaTerminada;
    }

    public void setProvaTerminada(boolean provaTerminada) {
        this.provaTerminada = provaTerminada;
    }

    public TipoProva getTipoProva() {
        return tipoProva;
    }

    public void setTipoProva(TipoProva tipoProva) {
        this.tipoProva = tipoProva;
    }

    public String getVersaoNome() {
        return versaoNome;
    }

    public void setVersaoNome(String versaoNome) {
        this.versaoNome = versaoNome;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Date getDataCriacao() {
        return dataCriacao;
    }

    public void setDataCriacao(Date dataCriacao) {
        this.dataCriacao = dataCriacao;
    }

    public boolean isMultiplaVersao() {
        return multiplaVersao;
    }

    public void setMultiplaVersao(boolean multiplaVersao) {
        this.multiplaVersao = multiplaVersao;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Prova)) {
            return false;
        }
        Prova other = (Prova) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "br.com.saber.certificacao.modelos.Prova[id=" + id + "]";
    }

    @Override
    public int compareTo(Prova o) {
        int toReturn = 0;
        toReturn = this.dataCriacao.compareTo(o.getDataCriacao());
        if(toReturn == 0){
            if(!this.provaTerminada){
                return -1;
            }
            if(!o.isProvaTerminada()){
                return 1;
            }
            toReturn = this.certificacao.compareTo(o.getCertificacao());
            if(toReturn == 0){
                toReturn = this.versaoNome.compareTo(o.getVersaoNome());
            }
        }
        if(toReturn == 0){
            toReturn = this.id.compareTo(o.getId());
        }
        return toReturn;
    }

    public void addQuestao(Questao questao, int numeroQuestao){
        getQuestoesDestaProva().add(new ProvaQuestao(this, questao, numeroQuestao));
    }
    
}
